using System;
using DevExpress.Data.Filtering;
using DevExpress.Xpo;
using SmartPeople.Framework.SecuritySpace;

namespace SmartPeople.Framework.Security.Providers.XPO
{
    internal class XPSecuritySecuredTypeProvider : ISecuritySecuredTypeProvider
    {
        private Guid applicationID;

        public XPSecuritySecuredTypeProvider(Guid applicationID)
        {
            this.applicationID = applicationID;
        }

        public int Count
        {
            get
            {
                GroupOperator criteria = new GroupOperator();
                criteria.Operands.Add(
                    new BinaryOperator("SecurityApplicationID", applicationID, BinaryOperatorType.Equal));
                XPCollection<XPSecuritySecuredType> xpCollection = new XPCollection<XPSecuritySecuredType>(criteria);
                return xpCollection.Count;
            }
        }

        #region CreateType(string typeName)

        public ISecuritySecuredType CreateType(string typeName)
        {
            return CreateType(typeName, "");
        }

        #endregion

        #region CreateType(string typeName, string baseTypeName)

        public ISecuritySecuredType CreateType(string typeName, string baseTypeName)
        {
            return CreateType(typeName, GetSecuredType(baseTypeName));
        }

        #endregion

        #region CreateType(string typeName, ISecuritySecuredType baseSecuredType)

        public ISecuritySecuredType CreateType(string typeName, ISecuritySecuredType baseSecuredType)
        {
            //XPSecuritySecuredType securedType = new XPSecuritySecuredType(typeName);
            XPSecuritySecuredType securedType = new XPSecuritySecuredType();
            securedType.Name = typeName;
            securedType.BaseSecuredType = baseSecuredType;
            securedType.SecurityApplicationID = applicationID;
            securedType.Save();
            return securedType;
        }

        #endregion

        #region GetSecuredType

        public ISecuritySecuredType GetSecuredType(string securedTypeName)
        {
            GroupOperator criteria = new GroupOperator(GroupOperatorType.And);
            criteria.Operands.Add(new BinaryOperator("Name", securedTypeName, BinaryOperatorType.Equal));
            criteria.Operands.Add(new BinaryOperator("SecurityApplicationID", applicationID, BinaryOperatorType.Equal));
            XPCollection<XPSecuritySecuredType> xpCollection = new XPCollection<XPSecuritySecuredType>(criteria);
            //xpCollection.Reload();
            if (xpCollection.Count == 1)
            {
                XPSecuritySecuredType securitySecuredType = xpCollection[0];
                return securitySecuredType;
            }
            return null;
        }

        #endregion

        #region GetAllSecuredTypes

        public ISecuritySecuredType[] GetAllSecuredTypes()
        {
            GroupOperator criteria = new GroupOperator();
            criteria.Operands.Add(new BinaryOperator("SecurityApplicationID", applicationID, BinaryOperatorType.Equal));
            XPCollection<XPSecuritySecuredType> xpCollection = new XPCollection<XPSecuritySecuredType>(criteria);
            ISecuritySecuredType[] securitySecuredTypes = new ISecuritySecuredType[xpCollection.Count];
            int length = securitySecuredTypes.Length;
            while (length > 0)
            {
                securitySecuredTypes[securitySecuredTypes.Length - length] =
                    xpCollection[securitySecuredTypes.Length - length];
                length--;
            }
            return securitySecuredTypes;
        }

        #endregion

        #region UpdateSecuredType

        public void UpdateSecuredType(ISecuritySecuredType securedType)
        {
            XPSecuritySecuredType xpsecuredType = (XPSecuritySecuredType) securedType;

            if (xpsecuredType != null)
            {
                xpsecuredType.Save();
                //Session session = Session.DefaultSession;
                //session.BeginTransaction();
                //try
                //{
                //    xpsecuredType.Save();
                //    session.CommitTransaction();
                //}
                //catch (Exception ex)
                //{
                //    session.RollbackTransaction();
                //    xpsecuredType.Reload();
                //    throw;
                //}
            }
            else
                throw new ArgumentException("Argument Path Exception!", "securedType");
        }

        #endregion

        #region SecuredTypeExists

        public bool SecuredTypeExists(string securedTypeName)
        {
            ISecuritySecuredType securitySecuredType = GetSecuredType(securedTypeName);
            return (securitySecuredType != null);
        }

        #endregion

        #region DeleteSecuredType

        public bool DeleteSecuredType(string securedTypeName, bool deleteAllRelatedData)
        {
            XPSecuritySecuredType securitySecuredType = (XPSecuritySecuredType) GetSecuredType(securedTypeName);
            if (securitySecuredType == null)
                return false;
            else
            {
                securitySecuredType.Delete();
                securitySecuredType.Session.PurgeDeletedObjects();
                return true;
            }
        }

        #endregion

        #region Clear

        public void Clear()
        {
            GroupOperator criteria = new GroupOperator(GroupOperatorType.And);
            criteria.Operands.Add(new BinaryOperator("SecurityApplicationID", applicationID, BinaryOperatorType.Equal));
            criteria.Operands.Add(new BinaryOperator("Name", "folder", BinaryOperatorType.NotEqual));
            criteria.Operands.Add(new BinaryOperator("Name", "unknownFileType", BinaryOperatorType.NotEqual));
            XPCollection<XPSecuritySecuredType> xpCollection = new XPCollection<XPSecuritySecuredType>(criteria);
            xpCollection.Session.Delete(xpCollection);
        }

        #endregion
    }
}